﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Common.Entitys;
using Common.Entitys.Messages;
using Common.Utlis;

namespace Common.Utils
{
    /// <summary>
    /// 进程间通信的帮助类(发送端)
    /// </summary>
    public class IPCSendHelp
    {
        /// <summary>
        /// 用于进程间通信的TCP
        /// </summary>
        private TcpClientHelp<BaseBytesMsg> m_TcpClientHelp = new TcpClientHelp<BaseBytesMsg>();

        /// <summary>
        /// 进程间通讯的缓存
        /// </summary>
        public ConcurrentQueue<object> m_IPCBytesCache = new ConcurrentQueue<object>();

        public IPCSendHelp()
        {
            MessageAggregator<IPCMsg>.Subscribe(OnIPCMsg);
        }

        private void OnIPCMsg(IPCMsg ipcMsg)
        {
            m_IPCBytesCache.Enqueue(ipcMsg);
        }

        private void Deal()
        {
            while (true)
            {
                try
                {

                    if (!m_IPCBytesCache.TryDequeue(out object entity))
                    {
                        Thread.Sleep(50);
                        continue;
                    }
                    m_TcpClientHelp.SendBytes(GetEntityByte(entity));
                }
                catch (Exception )
                {

                }
            }
        }

        public void Init()
        {
            Task.Factory.StartNew(Deal, TaskCreationOptions.LongRunning);
            m_TcpClientHelp = new TcpClientHelp<BaseBytesMsg>();
            m_TcpClientHelp.Init("127.0.0.1", 8086);
        }

        public void Add(object obj)
        {
            m_IPCBytesCache.Enqueue(obj);
        }

        private static Byte[] GetEntityByte(object obj)
        {
            byte[] sendBytes = SerializeHelp.SerializeToByteArray(obj);
            Byte[] lengthBytes = BitConverter.GetBytes(sendBytes.Length);

            byte[] finBytes = new byte[sendBytes.Length + lengthBytes.Length];
            //合并两个byte流
            Buffer.BlockCopy(lengthBytes, 0, finBytes, 0, lengthBytes.Length);//这种方法仅适用于字节数组
            Buffer.BlockCopy(sendBytes, 0, finBytes, lengthBytes.Length, sendBytes.Length);

            return finBytes;
        }
    }
}
